package ys.db2es.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import ys.db2es.pojo.IdAble;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 这工具类，有点没用，但是这次写了就写了，将就着用吧
 */
public class EsUtil {

    /**
     * 创建索引
     *
     * @param client   客户端
     * @param index    索引
     * @param shards   分片数
     * @param replicas 备份数
     * @param map      mappings
     */
    public static boolean createIndex(RestHighLevelClient client, String index, Integer shards, Integer replicas, Map<String, String[]> map) throws IOException {

        CreateIndexRequest request = new CreateIndexRequest(index);
        Settings settings = Settings.builder()
                .put("number_of_shards", shards)
                .put("number_of_replicas", replicas)
                .build();
        //这波代码写的没啥意义
        XContentBuilder mappings = XContentBuilder.builder(JsonXContent.jsonXContent)
                .startObject()
                .startObject("properties");
        for (Map.Entry<String, String[]> fieldMapEntry : map.entrySet()) {
            mappings.startObject(fieldMapEntry.getKey());
            for (String s : fieldMapEntry.getValue()) {
                String[] split = s.split("=");
                mappings.field(split[0], split[1]);
            }
            mappings.endObject();
        }
        mappings.endObject().endObject();
        request.settings(settings);
        request.mapping(mappings);
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }

    /**
     * 存入单个对象
     *
     * @param client 客户端
     * @param index  索引
     * @param obj    存入的对象
     * @param <T>    存入的对象的类型
     * @return 执行结果
     */
    public static <T extends IdAble> String putDoc(RestHighLevelClient client, String index, T obj) throws IOException {
        IndexRequest request = new IndexRequest(index);
        ObjectMapper objectMapper = new ObjectMapper();
        request.id(obj.getIdStr()).source(objectMapper.writeValueAsString(obj), XContentType.JSON);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        return response.getResult().getLowercase();
    }

    /**
     * 批量存入对象
     *
     * @param client 客户端
     * @param index  索引
     * @param objs   对象列表
     * @param <T>    对象类型
     * @return 执行结果
     */
    public static <T extends IdAble> String putDocs(RestHighLevelClient client, String index, List<T> objs) throws IOException {
        BulkRequest request = new BulkRequest(index);
        ObjectMapper objectMapper = new ObjectMapper();
        for (T obj : objs) {
            request.add(new IndexRequest().id(obj.getIdStr()).source(objectMapper.writeValueAsString(obj), XContentType.JSON));
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println(response.status().getStatus());
        return response.status().getStatus() + ":" + response.status().name();
    }

    /**
     * 获取该索引下的所有文档
     *
     * @param client 客户端
     * @param index  索引
     * @param <T>    对象类型
     * @return 执行结果
     */
    public static <T extends IdAble> List<T> getAllDocs(RestHighLevelClient client, String index, Class<T> clazz) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        List<T> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            T t = objectMapper.readValue(hit.getSourceAsString(), clazz);
            t.setIdStr(hit.getId());
            list.add(t);
        }
        return list;
    }

}
